import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useViewportStore = defineStore('viewport', () => {
  // 视口状态
  const viewport = ref({
    x: 0, // 视口左上角在画布上的 X 坐标
    y: 0, // 视口左上角在画布上的 Y 坐标
    zoom: 1, // 视口缩放比例
    rotation: 0, // 视口旋转角度
    minZoom: 0.1, // 视口最小缩放比例
    maxZoom: 5, // 视口最大缩放比例
    width: 800, // 视口宽度
    height: 600 // 视口宽度
  })

  // 视口历史
  const viewportHistory = ref([])
  const historyIndex = ref(-1)
  const maxHistorySize = ref(20)

  // 视口预设
  const viewportPresets = ref([
    { name: '适应画布', zoom: 'fit', description: '适应整个画布' },
    { name: '适应选择', zoom: 'fit-selection', description: '适应选中对象' },
    { name: '25%', zoom: 0.25, description: '25% 缩放' },
    { name: '50%', zoom: 0.5, description: '50% 缩放' },
    { name: '100%', zoom: 1, description: '100% 缩放' },
    { name: '200%', zoom: 2, description: '200% 缩放' },
    { name: '400%', zoom: 4, description: '400% 缩放' }
  ])

  // 计算属性
  const zoomPercentage = computed(() => Math.round(viewport.value.zoom * 100))
  const canZoomIn = computed(() => viewport.value.zoom < viewport.value.maxZoom)
  const canZoomOut = computed(() => viewport.value.zoom > viewport.value.minZoom)
  const canUndo = computed(() => historyIndex.value > 0)
  const canRedo = computed(() => historyIndex.value < viewportHistory.value.length - 1)

  // Actions
  const setViewport = (x, y, zoom, rotation = 0) => {
    const oldViewport = { ...viewport.value }
    viewport.value.x = x
    viewport.value.y = y
    viewport.value.zoom = Math.max(viewport.value.minZoom, Math.min(viewport.value.maxZoom, zoom))
    viewport.value.rotation = rotation
    
    addToHistory(oldViewport)
  }

  const panViewport = (deltaX, deltaY) => {
    const oldViewport = { ...viewport.value }
    
    viewport.value.x += deltaX
    viewport.value.y += deltaY
    
    addToHistory(oldViewport)
  }

  const zoomViewport = (zoom, centerX, centerY) => {
    const oldViewport = { ...viewport.value }
    const oldZoom = viewport.value.zoom
    const newZoom = Math.max(viewport.value.minZoom, Math.min(viewport.value.maxZoom, zoom))
    
    if (newZoom !== oldZoom) {
      // 以指定点为中心缩放
      const zoomRatio = newZoom / oldZoom
      viewport.value.x = centerX - (centerX - viewport.value.x) * zoomRatio
      viewport.value.y = centerY - (centerY - viewport.value.y) * zoomRatio
      viewport.value.zoom = newZoom
      
      addToHistory(oldViewport)
    }
  }

  const zoomIn = (factor = 1.2, centerX = null, centerY = null) => {
    const newZoom = viewport.value.zoom * factor
    const center = {
      x: centerX ?? viewport.value.width / 2,
      y: centerY ?? viewport.value.height / 2
    }
    
    zoomViewport(newZoom, center.x, center.y)
  }

  const zoomOut = (factor = 0.8, centerX = null, centerY = null) => {
    const newZoom = viewport.value.zoom * factor
    const center = {
      x: centerX ?? viewport.value.width / 2,
      y: centerY ?? viewport.value.height / 2
    }
    
    zoomViewport(newZoom, center.x, center.y)
  }

  const resetViewport = () => {
    const oldViewport = { ...viewport.value }
    
    viewport.value.x = 0
    viewport.value.y = 0
    viewport.value.zoom = 1
    viewport.value.rotation = 0
    
    addToHistory(oldViewport)
  }

  const fitToCanvas = (canvasWidth, canvasHeight, padding = 50) => {
    const oldViewport = { ...viewport.value }
    
    const scaleX = (viewport.value.width - padding * 2) / canvasWidth
    const scaleY = (viewport.value.height - padding * 2) / canvasHeight
    const scale = Math.min(scaleX, scaleY, 1)
    
    viewport.value.zoom = scale
    viewport.value.x = (viewport.value.width - canvasWidth * scale) / 2
    viewport.value.y = (viewport.value.height - canvasHeight * scale) / 2
    
    addToHistory(oldViewport)
  }

  const fitToSelection = (selectionBounds) => {
    if (!selectionBounds) return
    
    const oldViewport = { ...viewport.value }
    const padding = 50
    
    const scaleX = (viewport.value.width - padding * 2) / selectionBounds.width
    const scaleY = (viewport.value.height - padding * 2) / selectionBounds.height
    const scale = Math.min(scaleX, scaleY, viewport.value.maxZoom)
    
    viewport.value.zoom = scale
    viewport.value.x = (viewport.value.width - selectionBounds.width * scale) / 2 - selectionBounds.x * scale
    viewport.value.y = (viewport.value.height - selectionBounds.height * scale) / 2 - selectionBounds.y * scale
    
    addToHistory(oldViewport)
  }

  const rotateViewport = (angle) => {
    const oldViewport = { ...viewport.value }
    viewport.value.rotation = (viewport.value.rotation + angle) % 360
    addToHistory(oldViewport)
  }

  const setRotation = (angle) => {
    const oldViewport = { ...viewport.value }
    viewport.value.rotation = angle % 360
    addToHistory(oldViewport)
  }

  const setViewportSize = (width, height) => {
    viewport.value.width = width
    viewport.value.height = height
  }

  const setZoomLimits = (minZoom, maxZoom) => {
    viewport.value.minZoom = minZoom
    viewport.value.maxZoom = maxZoom
    
    // 确保当前缩放在限制范围内
    if (viewport.value.zoom < minZoom) {
      viewport.value.zoom = minZoom
    } else if (viewport.value.zoom > maxZoom) {
      viewport.value.zoom = maxZoom
    }
  }

  /**
   * 屏幕坐标转世界坐标
   * @param {number} screenX - 屏幕X坐标
   * @param {number} screenY - 屏幕Y坐标
   * @returns {Object} 世界坐标 {x, y}
   */
  const screenToWorld = (screenX, screenY) => {
    const cos = Math.cos(viewport.value.rotation * Math.PI / 180)
    const sin = Math.sin(viewport.value.rotation * Math.PI / 180)
    
    const dx = screenX - viewport.value.x
    const dy = screenY - viewport.value.y
    
    const worldX = (dx * cos + dy * sin) / viewport.value.zoom
    const worldY = (-dx * sin + dy * cos) / viewport.value.zoom
    
    return { x: worldX, y: worldY }
  }

  const worldToScreen = (worldX, worldY) => {
    const cos = Math.cos(viewport.value.rotation * Math.PI / 180)
    const sin = Math.sin(viewport.value.rotation * Math.PI / 180)
    
    const screenX = worldX * viewport.value.zoom * cos - worldY * viewport.value.zoom * sin + viewport.value.x
    const screenY = worldX * viewport.value.zoom * sin + worldY * viewport.value.zoom * cos + viewport.value.y
    
    return { x: screenX, y: screenY }
  }

  // 视口历史管理
  const addToHistory = (oldViewport) => {
    // 移除当前位置之后的所有历史记录
    viewportHistory.value = viewportHistory.value.slice(0, historyIndex.value + 1)
    
    // 添加新的历史记录
    viewportHistory.value.push({
      id: generateId(),
      viewport: { ...oldViewport },
      timestamp: Date.now()
    })
    
    historyIndex.value = viewportHistory.value.length - 1
    
    // 限制历史记录数量
    if (viewportHistory.value.length > maxHistorySize.value) {
      viewportHistory.value.shift()
      historyIndex.value--
    }
  }

  const undoViewport = () => {
    if (!canUndo.value) return
    
    historyIndex.value--
    const historyItem = viewportHistory.value[historyIndex.value]
    if (historyItem) {
      viewport.value = { ...historyItem.viewport }
    }
  }

  const redoViewport = () => {
    if (!canRedo.value) return
    
    historyIndex.value++
    const historyItem = viewportHistory.value[historyIndex.value]
    if (historyItem) {
      viewport.value = { ...historyItem.viewport }
    }
  }

  const clearViewportHistory = () => {
    viewportHistory.value = []
    historyIndex.value = -1
  }

  // 视口预设
  const applyPreset = (preset) => {
    if (preset.zoom === 'fit') {
      // 适应画布 - 需要画布尺寸
      fitToCanvas(800, 600) // 默认尺寸，实际应该从项目设置获取
    } else if (preset.zoom === 'fit-selection') {
      // 适应选择 - 需要选择边界
      // fitToSelection(selectionBounds)
    } else if (typeof preset.zoom === 'number') {
      const centerX = viewport.value.width / 2
      const centerY = viewport.value.height / 2
      zoomViewport(preset.zoom, centerX, centerY)
    }
  }

  const addPreset = (name, zoom, description = '') => {
    const newPreset = {
      name,
      zoom,
      description
    }
    
    viewportPresets.value.push(newPreset)
    return newPreset
  }

  const removePreset = (index) => {
    if (index >= 0 && index < viewportPresets.value.length) {
      viewportPresets.value.splice(index, 1)
    }
  }

  // 视口动画
  const animateToViewport = (targetViewport, duration = 500) => {
    const startViewport = { ...viewport.value }
    const startTime = Date.now()
    
    const animate = () => {
      const elapsed = Date.now() - startTime
      const progress = Math.min(elapsed / duration, 1)
      
      // 使用缓动函数
      const easeProgress = easeInOutCubic(progress)
      
      viewport.value.x = startViewport.x + (targetViewport.x - startViewport.x) * easeProgress
      viewport.value.y = startViewport.y + (targetViewport.y - startViewport.y) * easeProgress
      viewport.value.zoom = startViewport.zoom + (targetViewport.zoom - startViewport.zoom) * easeProgress
      viewport.value.rotation = startViewport.rotation + (targetViewport.rotation - startViewport.rotation) * easeProgress
      
      if (progress < 1) {
        requestAnimationFrame(animate)
      }
    }
    
    animate()
  }

  const easeInOutCubic = (t) => {
    return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2
  }

  // 视口导出/导入
  const exportViewport = () => {
    return {
      viewport: viewport.value,
      presets: viewportPresets.value,
      exportTime: Date.now()
    }
  }

  const importViewport = (data) => {
    if (data.viewport) {
      viewport.value = { ...viewport.value, ...data.viewport }
    }
    
    if (data.presets && Array.isArray(data.presets)) {
      viewportPresets.value = data.presets
    }
  }

  const reset = () => {
    viewport.value = {
      x: 0,
      y: 0,
      zoom: 1,
      rotation: 0,
      minZoom: 0.1,
      maxZoom: 5,
      width: 800,
      height: 600
    }
    
    viewportHistory.value = []
    historyIndex.value = -1
    
    viewportPresets.value = [
      { name: '适应画布', zoom: 'fit', description: '适应整个画布' },
      { name: '适应选择', zoom: 'fit-selection', description: '适应选中对象' },
      { name: '25%', zoom: 0.25, description: '25% 缩放' },
      { name: '50%', zoom: 0.5, description: '50% 缩放' },
      { name: '100%', zoom: 1, description: '100% 缩放' },
      { name: '200%', zoom: 2, description: '200% 缩放' },
      { name: '400%', zoom: 4, description: '400% 缩放' }
    ]
  }

  // 辅助函数
  const generateId = () => {
    return Date.now().toString(36) + Math.random().toString(36).substr(2)
  }

  return {
    // 状态
    viewport,
    viewportHistory,
    historyIndex,
    maxHistorySize,
    viewportPresets,
    
    // 计算属性
    zoomPercentage,
    canZoomIn,
    canZoomOut,
    canUndo,
    canRedo,
    
    // Actions
    setViewport,
    panViewport,
    zoomViewport,
    zoomIn,
    zoomOut,
    resetViewport,
    fitToCanvas,
    fitToSelection,
    rotateViewport,
    setRotation,
    setViewportSize,
    setZoomLimits,
    screenToWorld,
    worldToScreen,
    addToHistory,
    undoViewport,
    redoViewport,
    clearViewportHistory,
    applyPreset,
    addPreset,
    removePreset,
    animateToViewport,
    exportViewport,
    importViewport,
    reset
  }
})
